/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package mx.com.ingsw.service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import mx.com.ingsw.dao.exceptions.NonexistentEntityException;
import java.util.List;
import mx.com.ingsw.dao.*;
import mx.com.ingsw.model.*;

public class Verificacion {

    public String validaH(Alumno alu) throws ParseException, NonexistentEntityException, Exception {
        Date date = new Date(System.currentTimeMillis());
        SimpleDateFormat formato = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat formato1 = new SimpleDateFormat("HH:mm:ss");
        SimpleDateFormat formato2 = new SimpleDateFormat("yyyy-MM-dd");

        Date insInicio = null, insFin = null,
                bajaInicio = null, bajaFin = null,
                extemInicio = null, extemFin = null;
        Date horaSist = null;
        try {
             insInicio = formato.parse("2012-11-05 01:00:00");//Fechas de Inicio y Fin de Inscripcion Ordinarias
            //insFin = formato.parse("2012-10-31 23:00:00");
            insFin = formato.parse("2012-11-07 23:00:00");//Prueba para Borrar 

            //bajaInicio = formato.parse("2012-11-01 01:00:00");//Fechas de Altas y Bajas
            //bajaFin = formato.parse("2012-11-12 23:00:00");
            bajaInicio = formato.parse("2012-11-08 01:00:00");//Prueba para Borrar
            bajaFin = formato.parse("2012-11-10 23:00:00");//Prueba para Borrar

            //extemInicio = formato.parse("2012-11-13 01:00:00");//Fechas Extemporaneas de Inscripcion
            //extemFin = formato.parse("2012-11-15 23:00:00");
            extemInicio = formato.parse("2012-10-28 01:00:00");//Prueba para Borrar
            extemFin = formato.parse("2012-11-15 23:00:00");//Prueba para Borrar
        } catch (ParseException ex) {
        }

        AlumnoDAO ad = new AlumnoDAO();
        Alumno albd2 = ad.read(alu.getNoCuenta());
        FechainsDAO fid = new FechainsDAO();
        FechabajaDAO fbd = new FechabajaDAO();
        FechaextemDAO fed = new FechaextemDAO();
        Date datealu = null;
        String hora = "", fecha = "";
        //comparacion
        if ((date.compareTo(insInicio) >= 0 && date.compareTo(insFin) <= 0)) {
            fecha = formato2.format(fid.read(alu.getIdFechas()).getFechains());
            hora = formato1.format(fid.read(alu.getIdFechas()).getHorains());
            datealu = (Date) formato.parse(fecha + " " + hora);

            if (date.compareTo(datealu) >= 0) {
                if (albd2.getEdoSesion() < 1) {
                    return "Exito";
                } else {
                    return "Ya Estas Inscrito. Espera las Proximas Fechas";//Nuevo mensaje
                }
            } else {
                return "1Espera. Tu fecha de ingreso es: " + formato.format(datealu) + " La fecha del sistema es: " + formato.format(date);
            }
        }
        if ((date.compareTo(bajaInicio) >= 0 && date.compareTo(bajaFin) <= 0)) {
            fecha = formato2.format(fbd.read(alu.getIdFechas()).getFechabaja());
            hora = formato1.format(fbd.read(alu.getIdFechas()).getHorabaja());
            datealu = (Date) formato.parse(fecha + " " + hora);
            if (date.compareTo(datealu) >= 0) {
                if (albd2.getEdoSesion() <= 1) {
                    //albd2.setEdoSesion(2);   
                    return "Exito";
                }//nueva llave
                else {
                    return "Has Finalizado Tu Inscripcion. Espera el Periodo Extemporaneo";//Nuevo mensaje
                }
            }//nueva llave
            else {
                return "2Espera. Tu fecha de ingreso es: " + formato.format(datealu) + " La fecha del sistema es: " + formato.format(date);
            }
        }
        if ((date.compareTo(extemInicio) >= 0 && date.compareTo(extemFin) <= 0)) {
            fecha = formato2.format(fed.read(alu.getIdFechas()).getFechaextem());
            hora = formato1.format(fed.read(alu.getIdFechas()).getHoraextem());
            datealu = (Date) formato.parse(fecha + " " + hora);
            if (date.compareTo(datealu) >= 0) {
                if (albd2.getEdoSesion() <= 2) {
                    albd2.setEdoSesion(2);//
                    ad.update(albd2);
                    return "Exito";

                } else {
                    return "Has Finalizado Tu Inscripcion.";//Nuevo mensaje
                }
            } else {
                return "3Espera. Tu fecha de ingreso es: " + formato.format(datealu) + " La fecha del sistema es: " + formato.format(date);
            }
        }
        fecha = formato2.format(fed.read(alu.getIdFechas()).getFechaextem());
        hora = formato1.format(fed.read(alu.getIdFechas()).getHoraextem());
        datealu = (Date) formato.parse(fecha + " " + hora);
        return "Fuera del periodo de inscripción. la fecha del sistema es: " + formato.format(date) + "tu dia para entrar es " + formato.format(datealu);
    }

    public String validaEdS(Alumno alum) throws Exception {
        AlumnoDAO change = new AlumnoDAO();
        Alumno albd = change.read(alum.getNoCuenta());
        if (albd.getEdoSesion() < 1) {
            albd.setEdoSesion(1);
        } else if (albd.getEdoSesion() <= 1) {
                albd.setEdoSesion(2);
        } else if (albd.getEdoSesion() <= 2) {
                    albd.setEdoSesion(3);
        }
        change.update(albd);
        return "Exito";
    }

    public String validaMat(List<Inscripcion> li, Asignatura as) {
        AsignaturaDAO ad = new AsignaturaDAO();
        int tli = li.size(), cHum = 0, cTeo = 0, cLab = 0, cTot = 0;
        if ("teo".equals(as.getTipo())) {
            cTeo++;
        }
        if ("hum".equals(as.getTipo())) {
            cHum++;
        }
        if ("lab".equals(as.getTipo())) {
            cLab++;
        }
        for (int i = 0; i < tli; i++) {
            //li.get(i).getIdAsignatura();
            //as=ad.read(ins.getIdAsignatura());
            if ("teo".equals(ad.read(li.get(i).getIdAsignatura()).getTipo())) {
                cTeo++;
            }
            if ("hum".equals(ad.read(li.get(i).getIdAsignatura()).getTipo())) {
                cHum++;
            }

            if ("lab".equals(ad.read(li.get(i).getIdAsignatura()).getTipo())) {
                cLab++;
            }
        }
        cTot = cHum + cTeo;

        if (cHum > 2) {
            return "Solo puedes inscribir 2 humanisticas ";
        }
        if (cLab > 3) {
            return "Solo puedes inscribir 3 laboratorios";
        }
        if (cTot > 7) {
            return "Solo puedes inscribir 7 materias";
        } else {
            return "Exito";
        }
    }

    public String validaSeriacion(int aluCta, int asi) {
        HistorialDAO hd = new HistorialDAO();
        int ante;
        HistorialPK h = new HistorialPK();
        AsignaturaDAO ad = new AsignaturaDAO();
        //h.setIdAsignatura(asi);
        h.setNoCuenta(aluCta);
        //if(hd.read(h).getEstado()==4 && ad.read(asi).getAntecedente()==null)
        if (ad.read(asi).getAntecedente() == null) {
            return "Exito";
        }
        if (ad.read(asi).getAntecedente() != null) {
            ante = ad.read(asi).getAntecedente();
            h.setIdAsignatura(ante);
            if (hd.read(h) == null) {
                return "No has cursado la materia antecedente: " + ad.read(ante).getNombre();
            }
            if (hd.read(h).getEstado() == 4) {
                return "Exito";
            }
            if (hd.read(h).getEstado() == 2) {
                return "No puedes inscribir esta materia no has aprobado la antecedente: " + ad.read(ad.read(asi).getAntecedente()).getNombre();
            }
        }
        h.setIdAsignatura(asi);
        if (hd.read(h).getEstado() == 1) {
            return "Ya no puedes inscribir la materia, ya la has cursado 2 veces";
        } else {
            return "";
        }
    }

    public String validaLab(int asi, List<Inscripcion> liIns) {
        AsignaturaDAO ad = new AsignaturaDAO();
        if (ad.read(asi).getTipo().equals("teo") || ad.read(asi).getTipo().equals("hum")) {
            return "Exito";
        }
        if (true == liIns.isEmpty()) {
            if (ad.read(asi).getTipo().equals("lab")) {
                return "Tienes que inscribir la teoría correspondiente a ese laboratorio";
            }
        }
        if (ad.read(asi).getTipo().equals("lab")) {
            for (int i = 0; i < liIns.size(); i++) {
                if (ad.findByLaboratorio(asi).getIdAsignatura() == liIns.get(i).getIdAsignatura()) {
                    return "Exito";
                }
            }
        }
        return "No has inscrito la teoria " + ad.findByLaboratorio(asi).getNombre() + " correspondiente a ese laboratorio";
    }

    public String verificaBajaLab(List<Inscripcion> liIns, int cuenta, int asi) throws Exception {
        AsignaturaDAO ad = new AsignaturaDAO();
        InscripcionDAO id = new InscripcionDAO();
        GrupoDAO gd = new GrupoDAO();
        GrupoPK gpk = new GrupoPK();
        if (ad.read(asi).getLabLigado() == null) {
            return "Exito";
        }
        for (int i = 0; i < liIns.size(); i++) {
            /*if(liIns.get(i).getIdAsignatura()==asi)
            {
            return "Exito";
            }*/

            if (ad.read(asi).getLabLigado() == liIns.get(i).getIdAsignatura()) {
                int grupo = liIns.get(i).getIdGrupo();
                gpk.setNumeroGrupo(grupo);
                gpk.setIdAsignatura(ad.read(asi).getLabLigado());
                Grupo grbd = gd.read(gpk);
                id.delete(id.validaInscripcion(cuenta, ad.read(asi).getLabLigado()));
                grbd.setVacantes((int) grbd.getVacantes() + 1);
                gd.update(grbd);
                return "Exito";
            }
        }
        return "Exito";
    }
    
        public String ValidaBloqueMovil(Alumno alu, Grupo grins){
            int sbm = BloqueMovil(alu);
            AsignaturaDAO das = new AsignaturaDAO();
            Asignatura aux;
            aux = das.read(grins.getGrupoPK().getIdAsignatura());
            
            if(sbm + 3 < aux.getSemestre())
                return "No se puede inscribir " + aux.getNombre() + ". Se puede inscribir materias hasta el semestre: " + (sbm + 3);
            return "Exito";
        }
        private int BloqueMovil(Alumno alu){
            int semestre = 100;
            int i;
            HistorialDAO hid = new HistorialDAO();
            Historial auxh = new Historial();
            HistorialPK hpk = new HistorialPK();
            Asignatura auxa = new Asignatura();
            List<Asignatura> las = getAsignaturaHistorial(hid.getPorCuenta(alu.getNoCuenta()));
            hpk.setNoCuenta(alu.getNoCuenta());
            
            if(las.isEmpty() || las == null)
                return 1;
            
            for(i = 0; i < las.size(); i++){
                auxa = las.get(i);
                if(auxa == null)
                    break;
                hpk.setIdAsignatura(auxa.getIdAsignatura());
                auxh = hid.read(hpk);
                if(auxh.getEstado() == 1 || auxh.getEstado() == 2){
                    if(semestre > auxa.getSemestre())
                        semestre = auxa.getSemestre();
                }
            }
            return semestre;
        }
        
        private List<Asignatura> getAsignaturaHistorial (List<Historial> hil){
            Asignatura aux;
            AsignaturaDAO das = new AsignaturaDAO();
            List<Asignatura> las = new ArrayList<Asignatura>();
            int i;
            
            for(i = 0; i < hil.size(); i++){
                aux = das.read(hil.get(i).getHistorialPK().getIdAsignatura());
                las.add(aux);
            }
            return las;
        }
        public String ValidaHorarioGrupo(Grupo grins,  Alumno alu){
            int i;
            List<Inscripcion> lins = new ArrayList<Inscripcion>();
            AsignaturaDAO das = new AsignaturaDAO();
            InscripcionDAO dins = new InscripcionDAO();
            Inscripcion ins;
            GrupoDAO dgr = new GrupoDAO();
            GrupoPK grpk = new GrupoPK();
            Grupo gr;
            HorariomDAO dhm = new HorariomDAO();
            Horariom hm;
            
            Horariom hmins = dhm.read(grins.getHorariom());
            lins = dins.busca(alu.getNoCuenta());
            
            if(lins.isEmpty())
                return "Exito";
            for(i = 0; i < lins.size(); i++){
                ins = lins.get(i);
                grpk.setIdAsignatura(ins.getIdAsignatura());
                grpk.setNumeroGrupo(ins.getIdGrupo());
                gr = dgr.read(grpk);
                hm = dhm.read(gr.getHorariom());
                hm.getTiempoClaseFin();
                hm.getTiempoClaseIni();
                if(ComparaDiasHorario(hmins,hm)) // Checa si existen días que se traslapen
                    if(ComparaRangoHorario(hmins, hm)) //Si hay días que se traslapen, checa los horarios
                        return "Se traslapa el horario con: " + das.read(ins.getIdAsignatura()).getNombre() + " Clave: " + ins.getIdAsignatura(); 
            }
            return "Exito";
        }
        
        private boolean ComparaRangoHorario(Horariom hminscrita, Horariom hmgrnuevo){//Entradas: Primero el horario de la materia escrita y luego el horario del grupo que se quiere inscribir
            return (
             /*
             *  Primer Caso
             *       Compara que el horario sea exactamente el mismo
             */
                    (hminscrita.getTiempoClaseIni().equals(hmgrnuevo.getTiempoClaseIni()) &&
                        hminscrita.getTiempoClaseFin().equals(hmgrnuevo.getTiempoClaseFin()))   
                    ||
             /*
             *  Segundo Caso
                     * Compara que 
             */
                    (hminscrita.getTiempoClaseFin().compareTo(hmgrnuevo.getTiempoClaseIni()) > 0 &&
                        hminscrita.getTiempoClaseIni().compareTo(hmgrnuevo.getTiempoClaseFin()) < 0)
                    ); 
        }//Falso significa que no hay traslape, Verdadero significa que si lo hay
        
        private boolean ComparaDiasHorario(Horariom hminscrita, Horariom hmgrnuevo){
                    FechaclaseDAO dfc = new FechaclaseDAO();
                    String fcins, fcgr;
                    
                    fcins = dfc.read(hminscrita.getIdFechaClase()).getDia();
                    fcgr = dfc.read(hmgrnuevo.getIdFechaClase()).getDia();
                    
                    String ins[] = new String[3];
                    String gr[] = new String [3];
                    
                    ins = SeparaDias(fcins);
                    gr = SeparaDias(fcgr);
                    
                    return ComparaStringArr(ins, gr);                    
                    }
        
        private String[] SeparaDias(String dias){
            int inicio = 0, fin = 2;
            int i = 0;
            String aux[] = new String[3];
            do{//Separa las variables
                aux[i] = dias.substring(inicio,fin);
                inicio = fin + 1;
                fin = inicio +2;
                i++;
               }while(inicio < dias.length());
            return aux;
        }
        
        private boolean ComparaStringArr(String[] cad1, String[] cad2){
            int i, j;
            
            for(i = 0; i < cad1.length; i++){
                if(cad1[i] == null)
                    return false;
                for(j = 0; j < cad2.length; j++){
                    if(cad2[j] == null)
                        break;
                    if(cad1[i].equals(cad2[j]))
                        return true;
                }

            }
            return false;
        }
        public Inscripcion ValidaBaja(List<Inscripcion> lins, int id){
            Inscripcion aux;
            for(int i = 0; i < lins.size(); i++){
                aux = lins.get(i);
                if(aux.getIdAsignatura() == id){
                    return aux;
                }
            }  
            return null;
        }
}
